/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascendlic@<TBD>.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;

namespace TMF.AscendedThemeKit.Unthemed
{
    /// <summary>
    /// Represents border color information associated with a user interface (UI) element.
    /// </summary>
    [StructLayout(LayoutKind.Sequential), TypeConverter(typeof(BorderColorConverter))]
    public struct BorderColor
    {
        /// <summary>
        /// Provides a BorderColor object with SystemColors.ActiveCaptionText border colors.
        /// </summary>
        public static readonly BorderColor Empty;

        private bool _all;
        private Color _bottom;
        private Color _left;
        private Color _right;
        private Color _top;

        /// <summary>
        /// Initializes a new instance of the BorderColor class using the supplied border color for all edges.
        /// </summary>
        /// <param name="all">System.Drawing.Color. The color to be used the border for all edges.</param>
        /// <remarks>
        /// This constructor sets the Right, Left, Bottom, Top and All properties to the value of the all parameter.
        /// </remarks>
        public BorderColor(Color all)
        {
            this._all = true;

            this._left = all;
            this._top = all;
            this._right = all;
            this._bottom = all;

        }

        /// <summary>
        /// Initializes a new instance of the BorderColor class using the supplied colors for the edges.
        /// </summary>
        /// <param name="left">System.Drawing.Color. The border color for the left edge.</param>
        /// <param name="top">System.Drawing.Color. The border color for the top edge.</param>
        /// <param name="right">System.Drawing.Color. The border color for the right edge.</param>
        /// <param name="bottom">SSystem.Drawing.Color. The border color for the bottom edge.</param>
        /// <remarks>
        /// This constructor sets the Right, Left, Bottom, Top properties. If the parameters are all the same the All parameter is also set to the value.
        /// </remarks>
        public BorderColor(Color left, Color top, Color right, Color bottom)
        {
            this._left = left;
            this._top = top;
            this._right = right;
            this._bottom = bottom;

            this._all = (!(this._top != this._left) && !(this._top != this._right)) && (this._top == this._bottom);

        }

        /// <summary>
        /// Gets or sets the border color value for all the edges.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . The border color for all edges if the same; otherwise SystemColors.ActiveCaptionText.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        [Browsable(true), RefreshProperties(RefreshProperties.All)]
        public Color All
        {
            get
            {
                if (!this._all)
                {
                    return SystemColors.ActiveCaptionText;

                }

                return this._top;

            }

            set
            {
                if (this._all && (this._top == value))
                {
                    return;

                }

                this._all = true;

                this._bottom = value;
                this._right = value;
                this._left = value;
                this._top = value;

            }

        }

        /// <summary>
        /// Gets or sets the border color value for the bottom edge.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . The border color for the bottom edge.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        /// <remarks>
        /// Setting this value can also alter the All property.
        /// </remarks>
        [RefreshProperties(RefreshProperties.All)]
        public Color Bottom
        {
            get
            {
                return this._bottom;

            }

            set
            {
                this._bottom = value;

            }

        }

        /// <summary>
        /// Gets or sets the border color value for the left edge.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . The border color for the left edge.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        /// <remarks>
        /// Setting this value can also alter the All property.
        /// </remarks>
        [RefreshProperties(RefreshProperties.All)]
        public Color Left
        {
            get
            {
                return this._left;

            }

            set
            {
                this._left = value;

            }

        }

        /// <summary>
        /// Gets or sets the border color value for the right edge.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . The border color for the right edge.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        /// <remarks>
        /// Setting this value can also alter the All property.
        /// </remarks>
        [RefreshProperties(RefreshProperties.All)]
        public Color Right
        {
            get
            {
                return this._right;

            }

            set
            {
                this._right = value;

            }

        }

        /// <summary>
        /// Gets or sets the border color value for the top edge.
        /// </summary>
        /// <value>
        /// <para>
        /// System.Drawing.Color . The border color for the top edge.
        /// </para>
        /// <para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        /// <remarks>
        /// Setting this value can also alter the All property.
        /// </remarks>
        [RefreshProperties(RefreshProperties.All)]
        public Color Top
        {
            get
            {
                return this._top;

            }

            set
            {
                this._top = value;

            }

        }

        /// <summary>
        /// Returns if the All property has been used.
        /// </summary>
        /// <returns>True or false</returns>
        public bool ShouldSerializeAll()
        {
            return this._all;

        }

        /// <summary>
        /// Returns a string that contains the border color values for an instance of the BorderColor class.
        /// </summary>
        /// <returns>
        /// <para>
        /// System.String . 
        /// </para>
        /// <para>
        /// A String that represents the current BorderColor.
        /// </para>
        /// </returns>
        /// <remarks>
        /// <para>
        /// This method returns a string containing the labeled values of the border color for all four edges.
        /// </para>
        /// <para>
        /// This method overrides ToString.
        /// </para>
        /// </remarks>
        public override string ToString()
        {
            string[] textArray = new string[9] { "{Left=", this.Left.ToString(), ",Top=", this.Top.ToString(), ",Right=", this.Right.ToString(), ",Bottom=", this.Bottom.ToString(), "}" };
            return string.Concat(textArray);

        }

        /// <summary>
        /// Serves as a hash function for the BorderColor type, suitable for use in hashing algorithms and data structures like a hash table.
        /// </summary>
        /// <returns>
        /// <para>
        /// System.Int32
        /// </para>
        /// <para>
        /// A hash code for the BorderColor object.
        /// </para>
        /// </returns>
        public override int GetHashCode()
        {
            return (this.Left.GetHashCode() ^ this.Top.GetHashCode() ^ this.Right.GetHashCode() ^ this.Bottom.GetHashCode());

        }

        /// <summary>
        /// Determines whether the specified object is equal to the current Object.
        /// </summary>
        /// <param name="obj">The Object to compare with the current Object.</param>
        /// <returns>true if the specified Object is equal to the current Object; otherwise, false.</returns>
        public override bool Equals(object obj)
        {
            if (obj is BorderColor)
            {
                BorderColor borderColor = (BorderColor)obj;
                if (((borderColor._all == this._all) && (borderColor._top == this._top)) && ((borderColor._left == this._left) && (borderColor._bottom == this._bottom)))
                {
                    return (borderColor.Right == this._right);

                }

            }

            return false;

        }

        /// <summary>
        /// Tests whether two specified BorderColor objects are equivalent.
        /// </summary>
        /// <param name="borderColor1">BorderColor. A Border to test.</param>
        /// <param name="borderColor2">BorderColor. A Border to test.</param>
        /// <returns>System.Boolean . true if the two BorderColor objects are equivalent; otherwise, false.</returns>
        public static bool operator ==(BorderColor borderColor1, BorderColor borderColor2)
        {
            return borderColor1.Equals(borderColor2);

        }

        /// <summary>
        /// Tests whether two specified Border objects are not equivalent.
        /// </summary>
        /// <param name="borderColor1">Border. A Border to test.</param>
        /// <param name="borderColor2">Border. A Border to test.</param>
        /// <returns>System.Boolean . true if the two Border objects are different; otherwise, false.</returns>
        public static bool operator !=(BorderColor borderColor1, BorderColor borderColor2)
        {
            return !(borderColor1.Equals(borderColor2));

        }

    }

}
